{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "executionInfo": {
     "elapsed": 6289,
     "status": "ok",
     "timestamp": 1649958316791,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "NK5O2SUrK_xL"
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn.functional as F\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import random\n",
    "import rl_utils"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 17090,
     "status": "ok",
     "timestamp": 1649958333876,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "2pfzwJiJK_xO",
    "outputId": "e7050004-2701-4bec-f531-16774f1eb026"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Obtaining file:///content/multiagent-particle-envs\n",
      "Requirement already satisfied: gym in /usr/local/lib/python3.7/dist-packages (from multiagent==0.0.1) (0.17.3)\n",
      "Collecting numpy-stl\n",
      "  Downloading numpy-stl-2.16.3.tar.gz (772 kB)\n",
      "\u001b[K     |████████████████████████████████| 772 kB 21.9 MB/s \n",
      "\u001b[?25hRequirement already satisfied: pyglet<=1.5.0,>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from gym->multiagent==0.0.1) (1.5.0)\n",
      "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from gym->multiagent==0.0.1) (1.4.1)\n",
      "Requirement already satisfied: numpy>=1.10.4 in /usr/local/lib/python3.7/dist-packages (from gym->multiagent==0.0.1) (1.21.5)\n",
      "Requirement already satisfied: cloudpickle<1.7.0,>=1.2.0 in /usr/local/lib/python3.7/dist-packages (from gym->multiagent==0.0.1) (1.3.0)\n",
      "Requirement already satisfied: future in /usr/local/lib/python3.7/dist-packages (from pyglet<=1.5.0,>=1.4.0->gym->multiagent==0.0.1) (0.16.0)\n",
      "Requirement already satisfied: python-utils>=1.6.2 in /usr/local/lib/python3.7/dist-packages (from numpy-stl->multiagent==0.0.1) (3.1.0)\n",
      "Building wheels for collected packages: numpy-stl\n",
      "  Building wheel for numpy-stl (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
      "  Created wheel for numpy-stl: filename=numpy_stl-2.16.3-cp37-cp37m-linux_x86_64.whl size=137073 sha256=6b9d2bdad7dffab23f7c8b6c516fff61e630c72ab40184578d691a91dd8f583c\n",
      "  Stored in directory: /root/.cache/pip/wheels/06/f4/db/7fac39962a6ba79b7e740892042332083924bff552d4bef41e\n",
      "Successfully built numpy-stl\n",
      "Installing collected packages: numpy-stl, multiagent\n",
      "  Running setup.py develop for multiagent\n",
      "Successfully installed multiagent-0.0.1 numpy-stl-2.16.3\n",
      "\u001b[K     |████████████████████████████████| 1.5 MB 14.7 MB/s \n",
      "\u001b[?25h  Building wheel for gym (setup.py) ... \u001b[?25l\u001b[?25hdone\n"
     ]
    }
   ],
   "source": [
    "!git clone https://github.com/boyu-ai/multiagent-particle-envs.git --quiet\n",
    "!pip install -e multiagent-particle-envs\n",
    "import sys\n",
    "sys.path.append(\"multiagent-particle-envs\")\n",
    "# 由于multiagent-pariticle-env底层的实现有一些版本问题,因此gym需要改为可用的版本\n",
    "!pip install --upgrade gym==0.10.5 -q\n",
    "import gym\n",
    "from multiagent.environment import MultiAgentEnv\n",
    "import multiagent.scenarios as scenarios\n",
    "\n",
    "\n",
    "def make_env(scenario_name):\n",
    "    # 从环境文件脚本中创建环境\n",
    "    scenario = scenarios.load(scenario_name + \".py\").Scenario()\n",
    "    world = scenario.make_world()\n",
    "    env = MultiAgentEnv(world, scenario.reset_world, scenario.reward,\n",
    "                        scenario.observation)\n",
    "    return env"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "executionInfo": {
     "elapsed": 8,
     "status": "ok",
     "timestamp": 1649958333876,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "-dpzMRpWK_xP"
   },
   "outputs": [],
   "source": [
    "def onehot_from_logits(logits, eps=0.01):\n",
    "    ''' 生成最优动作的独热（one-hot）形式 '''\n",
    "    argmax_acs = (logits == logits.max(1, keepdim=True)[0]).float()\n",
    "    # 生成随机动作,转换成独热形式\n",
    "    rand_acs = torch.autograd.Variable(torch.eye(logits.shape[1])[[\n",
    "        np.random.choice(range(logits.shape[1]), size=logits.shape[0])\n",
    "    ]],\n",
    "                                       requires_grad=False).to(logits.device)\n",
    "    # 通过epsilon-贪婪算法来选择用哪个动作\n",
    "    return torch.stack([\n",
    "        argmax_acs[i] if r > eps else rand_acs[i]\n",
    "        for i, r in enumerate(torch.rand(logits.shape[0]))\n",
    "    ])\n",
    "\n",
    "\n",
    "def sample_gumbel(shape, eps=1e-20, tens_type=torch.FloatTensor):\n",
    "    \"\"\"从Gumbel(0,1)分布中采样\"\"\"\n",
    "    U = torch.autograd.Variable(tens_type(*shape).uniform_(),\n",
    "                                requires_grad=False)\n",
    "    return -torch.log(-torch.log(U + eps) + eps)\n",
    "\n",
    "\n",
    "def gumbel_softmax_sample(logits, temperature):\n",
    "    \"\"\" 从Gumbel-Softmax分布中采样\"\"\"\n",
    "    y = logits + sample_gumbel(logits.shape, tens_type=type(logits.data)).to(\n",
    "        logits.device)\n",
    "    return F.softmax(y / temperature, dim=1)\n",
    "\n",
    "\n",
    "def gumbel_softmax(logits, temperature=1.0):\n",
    "    \"\"\"从Gumbel-Softmax分布中采样,并进行离散化\"\"\"\n",
    "    y = gumbel_softmax_sample(logits, temperature)\n",
    "    y_hard = onehot_from_logits(y)\n",
    "    y = (y_hard.to(logits.device) - y).detach() + y\n",
    "    # 返回一个y_hard的独热量,但是它的梯度是y,我们既能够得到一个与环境交互的离散动作,又可以\n",
    "    # 正确地反传梯度\n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "executionInfo": {
     "elapsed": 8,
     "status": "ok",
     "timestamp": 1649958333877,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "RPIC_vPUK_xQ"
   },
   "outputs": [],
   "source": [
    "class TwoLayerFC(torch.nn.Module):\n",
    "    def __init__(self, num_in, num_out, hidden_dim):\n",
    "        super().__init__()\n",
    "        self.fc1 = torch.nn.Linear(num_in, hidden_dim)\n",
    "        self.fc2 = torch.nn.Linear(hidden_dim, hidden_dim)\n",
    "        self.fc3 = torch.nn.Linear(hidden_dim, num_out)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        return self.fc3(x)\n",
    "\n",
    "\n",
    "class DDPG:\n",
    "    ''' DDPG算法 '''\n",
    "    def __init__(self, state_dim, action_dim, critic_input_dim, hidden_dim,\n",
    "                 actor_lr, critic_lr, device):\n",
    "        self.actor = TwoLayerFC(state_dim, action_dim, hidden_dim).to(device)\n",
    "        self.target_actor = TwoLayerFC(state_dim, action_dim,\n",
    "                                       hidden_dim).to(device)\n",
    "        self.critic = TwoLayerFC(critic_input_dim, 1, hidden_dim).to(device)\n",
    "        self.target_critic = TwoLayerFC(critic_input_dim, 1,\n",
    "                                        hidden_dim).to(device)\n",
    "        self.target_critic.load_state_dict(self.critic.state_dict())\n",
    "        self.target_actor.load_state_dict(self.actor.state_dict())\n",
    "        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(),\n",
    "                                                lr=actor_lr)\n",
    "        self.critic_optimizer = torch.optim.Adam(self.critic.parameters(),\n",
    "                                                 lr=critic_lr)\n",
    "\n",
    "    def take_action(self, state, explore=False):\n",
    "        action = self.actor(state)\n",
    "        if explore:\n",
    "            action = gumbel_softmax(action)\n",
    "        else:\n",
    "            action = onehot_from_logits(action)\n",
    "        return action.detach().cpu().numpy()[0]\n",
    "\n",
    "    def soft_update(self, net, target_net, tau):\n",
    "        for param_target, param in zip(target_net.parameters(),\n",
    "                                       net.parameters()):\n",
    "            param_target.data.copy_(param_target.data * (1.0 - tau) +\n",
    "                                    param.data * tau)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "executionInfo": {
     "elapsed": 7,
     "status": "ok",
     "timestamp": 1649958333877,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "UgJlmdo2K_xR"
   },
   "outputs": [],
   "source": [
    "class MADDPG:\n",
    "    def __init__(self, env, device, actor_lr, critic_lr, hidden_dim,\n",
    "                 state_dims, action_dims, critic_input_dim, gamma, tau):\n",
    "        self.agents = []\n",
    "        for i in range(len(env.agents)):\n",
    "            self.agents.append(\n",
    "                DDPG(state_dims[i], action_dims[i], critic_input_dim,\n",
    "                     hidden_dim, actor_lr, critic_lr, device))\n",
    "        self.gamma = gamma\n",
    "        self.tau = tau\n",
    "        self.critic_criterion = torch.nn.MSELoss()\n",
    "        self.device = device\n",
    "\n",
    "    @property\n",
    "    def policies(self):\n",
    "        return [agt.actor for agt in self.agents]\n",
    "\n",
    "    @property\n",
    "    def target_policies(self):\n",
    "        return [agt.target_actor for agt in self.agents]\n",
    "\n",
    "    def take_action(self, states, explore):\n",
    "        states = [\n",
    "            torch.tensor([states[i]], dtype=torch.float, device=self.device)\n",
    "            for i in range(len(env.agents))\n",
    "        ]\n",
    "        return [\n",
    "            agent.take_action(state, explore)\n",
    "            for agent, state in zip(self.agents, states)\n",
    "        ]\n",
    "\n",
    "    def update(self, sample, i_agent):\n",
    "        obs, act, rew, next_obs, done = sample\n",
    "        cur_agent = self.agents[i_agent]\n",
    "\n",
    "        cur_agent.critic_optimizer.zero_grad()\n",
    "        all_target_act = [\n",
    "            onehot_from_logits(pi(_next_obs))\n",
    "            for pi, _next_obs in zip(self.target_policies, next_obs)\n",
    "        ]\n",
    "        target_critic_input = torch.cat((*next_obs, *all_target_act), dim=1)\n",
    "        target_critic_value = rew[i_agent].view(\n",
    "            -1, 1) + self.gamma * cur_agent.target_critic(\n",
    "                target_critic_input) * (1 - done[i_agent].view(-1, 1))\n",
    "        critic_input = torch.cat((*obs, *act), dim=1)\n",
    "        critic_value = cur_agent.critic(critic_input)\n",
    "        critic_loss = self.critic_criterion(critic_value,\n",
    "                                            target_critic_value.detach())\n",
    "        critic_loss.backward()\n",
    "        cur_agent.critic_optimizer.step()\n",
    "\n",
    "        cur_agent.actor_optimizer.zero_grad()\n",
    "        cur_actor_out = cur_agent.actor(obs[i_agent])\n",
    "        cur_act_vf_in = gumbel_softmax(cur_actor_out)\n",
    "        all_actor_acs = []\n",
    "        for i, (pi, _obs) in enumerate(zip(self.policies, obs)):\n",
    "            if i == i_agent:\n",
    "                all_actor_acs.append(cur_act_vf_in)\n",
    "            else:\n",
    "                all_actor_acs.append(onehot_from_logits(pi(_obs)))\n",
    "        vf_in = torch.cat((*obs, *all_actor_acs), dim=1)\n",
    "        actor_loss = -cur_agent.critic(vf_in).mean()\n",
    "        actor_loss += (cur_actor_out**2).mean() * 1e-3\n",
    "        actor_loss.backward()\n",
    "        cur_agent.actor_optimizer.step()\n",
    "\n",
    "    def update_all_targets(self):\n",
    "        for agt in self.agents:\n",
    "            agt.soft_update(agt.actor, agt.target_actor, self.tau)\n",
    "            agt.soft_update(agt.critic, agt.target_critic, self.tau)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "executionInfo": {
     "elapsed": 5,
     "status": "ok",
     "timestamp": 1649958334400,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "HpnsWpsFK_xS"
   },
   "outputs": [],
   "source": [
    "num_episodes = 5000\n",
    "episode_length = 25  # 每条序列的最大长度\n",
    "buffer_size = 100000\n",
    "hidden_dim = 64\n",
    "actor_lr = 1e-2\n",
    "critic_lr = 1e-2\n",
    "gamma = 0.95\n",
    "tau = 1e-2\n",
    "batch_size = 1024\n",
    "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "update_interval = 100\n",
    "minimal_size = 4000\n",
    "\n",
    "env_id = \"simple_adversary\"\n",
    "env = make_env(env_id)\n",
    "replay_buffer = rl_utils.ReplayBuffer(buffer_size)\n",
    "\n",
    "state_dims = []\n",
    "action_dims = []\n",
    "for action_space in env.action_space:\n",
    "    action_dims.append(action_space.n)\n",
    "for state_space in env.observation_space:\n",
    "    state_dims.append(state_space.shape[0])\n",
    "critic_input_dim = sum(state_dims) + sum(action_dims)\n",
    "\n",
    "maddpg = MADDPG(env, device, actor_lr, critic_lr, hidden_dim, state_dims,\n",
    "                action_dims, critic_input_dim, gamma, tau)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 639428,
     "status": "ok",
     "timestamp": 1649958973823,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "oJYndDnWK_xS",
    "outputId": "e2e0b3de-b9b7-45ee-ef3b-84786c9dfa58"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:21: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at  ../torch/csrc/utils/tensor_new.cpp:201.)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 100, [-162.09349111961225, 9.000666921056728, 9.000666921056728]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/content/rl_utils.py:17: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.\n",
      "  return np.array(state), action, reward, np.array(next_state), done\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 200, [-121.85087049356082, 20.082544683591127, 20.082544683591127]\n",
      "Episode: 300, [-28.086124816732802, -23.51493605339695, -23.51493605339695]\n",
      "Episode: 400, [-35.91437846570877, -6.574264880829929, -6.574264880829929]\n",
      "Episode: 500, [-12.83238365700212, -5.402338391212475, -5.402338391212475]\n",
      "Episode: 600, [-11.692053500921567, 2.904343355450921, 2.904343355450921]\n",
      "Episode: 700, [-11.21261001095729, 6.13003213658482, 6.13003213658482]\n",
      "Episode: 800, [-12.581086056359824, 7.13450533137511, 7.13450533137511]\n",
      "Episode: 900, [-10.932824468382302, 7.534917449533213, 7.534917449533213]\n",
      "Episode: 1000, [-10.454432036663551, 7.467940904661571, 7.467940904661571]\n",
      "Episode: 1100, [-10.099017183836345, 6.764091427064233, 6.764091427064233]\n",
      "Episode: 1200, [-9.970202627245511, 6.839233648010857, 6.839233648010857]\n",
      "Episode: 1300, [-8.23988889957424, 5.928539785965939, 5.928539785965939]\n",
      "Episode: 1400, [-7.618319791914515, 5.4721657785273665, 5.4721657785273665]\n",
      "Episode: 1500, [-9.528028248906292, 6.716548343395567, 6.716548343395567]\n",
      "Episode: 1600, [-9.27198788506915, 6.25794360791615, 6.25794360791615]\n",
      "Episode: 1700, [-9.439913314907297, 6.552076175517556, 6.552076175517556]\n",
      "Episode: 1800, [-9.41018120255451, 6.170898260988019, 6.170898260988019]\n",
      "Episode: 1900, [-8.293080671760299, 5.710058304479939, 5.710058304479939]\n",
      "Episode: 2000, [-8.876670052284371, 5.804116304916539, 5.804116304916539]\n",
      "Episode: 2100, [-8.20415531215746, 5.170909738207094, 5.170909738207094]\n",
      "Episode: 2200, [-8.773275999321958, 4.961748911238369, 4.961748911238369]\n",
      "Episode: 2300, [-8.06474017837516, 5.223795184183733, 5.223795184183733]\n",
      "Episode: 2400, [-6.587706872401325, 4.366625235204875, 4.366625235204875]\n",
      "Episode: 2500, [-7.691312056289927, 4.856855290592445, 4.856855290592445]\n",
      "Episode: 2600, [-8.813560406139358, 5.508815842509804, 5.508815842509804]\n",
      "Episode: 2700, [-7.056761924960759, 4.758538712873507, 4.758538712873507]\n",
      "Episode: 2800, [-8.68842389422384, 5.661161581099521, 5.661161581099521]\n",
      "Episode: 2900, [-7.930406418494052, 4.366106102743839, 4.366106102743839]\n",
      "Episode: 3000, [-8.114850902595816, 5.1274853968197265, 5.1274853968197265]\n",
      "Episode: 3100, [-8.381402942461598, 5.093518450135181, 5.093518450135181]\n",
      "Episode: 3200, [-9.493930234055618, 5.472500034114433, 5.472500034114433]\n",
      "Episode: 3300, [-8.53312311113189, 4.963767973071618, 4.963767973071618]\n",
      "Episode: 3400, [-9.229941671093316, 5.555036222150763, 5.555036222150763]\n",
      "Episode: 3500, [-10.67973248813069, 6.0258368192309115, 6.0258368192309115]\n",
      "Episode: 3600, [-8.785648619797922, 5.360050159370962, 5.360050159370962]\n",
      "Episode: 3700, [-10.050750001897885, 5.962048108721202, 5.962048108721202]\n",
      "Episode: 3800, [-6.673053043055956, 3.732181204778823, 3.732181204778823]\n",
      "Episode: 3900, [-10.567190838130202, 5.705831860427992, 5.705831860427992]\n",
      "Episode: 4000, [-9.288291495674969, 5.298166543261745, 5.298166543261745]\n",
      "Episode: 4100, [-9.433352212890984, 6.016868802323455, 6.016868802323455]\n",
      "Episode: 4200, [-8.573388252905312, 4.673785791835532, 4.673785791835532]\n",
      "Episode: 4300, [-8.466209564326363, 5.482892841309288, 5.482892841309288]\n",
      "Episode: 4400, [-9.988322102926736, 5.5203824927807155, 5.5203824927807155]\n",
      "Episode: 4500, [-7.4937676078180155, 4.730897948468445, 4.730897948468445]\n",
      "Episode: 4600, [-8.755589567322176, 5.494709505886223, 5.494709505886223]\n",
      "Episode: 4700, [-9.16743075823155, 5.234841527940852, 5.234841527940852]\n",
      "Episode: 4800, [-8.597439825247829, 4.615078133167369, 4.615078133167369]\n",
      "Episode: 4900, [-9.918505853931377, 5.08561749388552, 5.08561749388552]\n",
      "Episode: 5000, [-10.16405662517592, 5.43335871613719, 5.43335871613719]\n"
     ]
    }
   ],
   "source": [
    "def evaluate(env_id, maddpg, n_episode=10, episode_length=25):\n",
    "    # 对学习的策略进行评估,此时不会进行探索\n",
    "    env = make_env(env_id)\n",
    "    returns = np.zeros(len(env.agents))\n",
    "    for _ in range(n_episode):\n",
    "        obs = env.reset()\n",
    "        for t_i in range(episode_length):\n",
    "            actions = maddpg.take_action(obs, explore=False)\n",
    "            obs, rew, done, info = env.step(actions)\n",
    "            rew = np.array(rew)\n",
    "            returns += rew / n_episode\n",
    "    return returns.tolist()\n",
    "\n",
    "\n",
    "return_list = []  # 记录每一轮的回报（return）\n",
    "total_step = 0\n",
    "for i_episode in range(num_episodes):\n",
    "    state = env.reset()\n",
    "    # ep_returns = np.zeros(len(env.agents))\n",
    "    for e_i in range(episode_length):\n",
    "        actions = maddpg.take_action(state, explore=True)\n",
    "        next_state, reward, done, _ = env.step(actions)\n",
    "        replay_buffer.add(state, actions, reward, next_state, done)\n",
    "        state = next_state\n",
    "\n",
    "        total_step += 1\n",
    "        if replay_buffer.size(\n",
    "        ) >= minimal_size and total_step % update_interval == 0:\n",
    "            sample = replay_buffer.sample(batch_size)\n",
    "\n",
    "            def stack_array(x):\n",
    "                rearranged = [[sub_x[i] for sub_x in x]\n",
    "                              for i in range(len(x[0]))]\n",
    "                return [\n",
    "                    torch.FloatTensor(np.vstack(aa)).to(device)\n",
    "                    for aa in rearranged\n",
    "                ]\n",
    "\n",
    "            sample = [stack_array(x) for x in sample]\n",
    "            for a_i in range(len(env.agents)):\n",
    "                maddpg.update(sample, a_i)\n",
    "            maddpg.update_all_targets()\n",
    "    if (i_episode + 1) % 100 == 0:\n",
    "        ep_returns = evaluate(env_id, maddpg, n_episode=100)\n",
    "        return_list.append(ep_returns)\n",
    "        print(f\"Episode: {i_episode+1}, {ep_returns}\")\n",
    "\n",
    "# Episode: 100, [-139.85078880125366, 24.84409588589504, 24.84409588589504]\n",
    "\n",
    "# /content/rl_utils.py:17: VisibleDeprecationWarning: Creating an ndarray from ragged\n",
    "# nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different\n",
    "# lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=\n",
    "# object' when creating the ndarray\n",
    "#   return np.array(state), action, reward, np.array(next_state), done\n",
    "\n",
    "# Episode: 200, [-105.11447331630691, -4.667816632926483, -4.667816632926483]\n",
    "# Episode: 300, [-31.04371751870054, 2.367667721218739, 2.367667721218739]\n",
    "# Episode: 400, [-25.856803405338162, -1.6019954659169862, -1.6019954659169862]\n",
    "# Episode: 500, [-14.863629584466256, -6.493559215483058, -6.493559215483058]\n",
    "# Episode: 600, [-11.753253499724337, 1.1278364537452759, 1.1278364537452759]\n",
    "# Episode: 700, [-12.55948132966949, 0.36995365890528387, 0.36995365890528387]\n",
    "# Episode: 800, [-11.204469505024559, 5.799833097835371, 5.799833097835371]\n",
    "# Episode: 900, [-12.793323601010943, 7.0357387891514716, 7.0357387891514716]\n",
    "# Episode: 1000, [-9.731828562147946, 5.203205531782827, 5.203205531782827]\n",
    "# Episode: 1100, [-8.510131349426718, 5.2461119857635135, 5.2461119857635135]\n",
    "# Episode: 1200, [-9.585692738161287, 6.777259476592237, 6.777259476592237]\n",
    "# Episode: 1300, [-9.826005870972006, 7.207743730178556, 7.207743730178556]\n",
    "# Episode: 1400, [-8.566589499183216, 6.2620796176791, 6.2620796176791]\n",
    "# Episode: 1500, [-8.543261572521422, 5.8545569515458755, 5.8545569515458755]\n",
    "# Episode: 1600, [-9.719611039111387, 6.136607469223544, 6.136607469223544]\n",
    "# Episode: 1700, [-8.2925932025312, 5.435361693227948, 5.435361693227948]\n",
    "# Episode: 1800, [-8.959067279108076, 5.990426636679429, 5.990426636679429]\n",
    "# Episode: 1900, [-8.8242500783286, 5.307928537097473, 5.307928537097473]\n",
    "# Episode: 2000, [-8.20281209652912, 5.689542567717828, 5.689542567717828]\n",
    "# Episode: 2100, [-9.04772055064216, 5.583820408577938, 5.583820408577938]\n",
    "# Episode: 2200, [-8.50059251561189, 5.6745737134871215, 5.6745737134871215]\n",
    "# Episode: 2300, [-6.878826441166284, 4.451387010062865, 4.451387010062865]\n",
    "# Episode: 2400, [-9.324710297045764, 5.414272587118738, 5.414272587118738]\n",
    "# Episode: 2500, [-8.215515333155677, 5.0714473072251085, 5.0714473072251085]\n",
    "# Episode: 2600, [-9.710948754211286, 5.945957102784014, 5.945957102784014]\n",
    "# Episode: 2700, [-6.95987837179912, 4.306175766599912, 4.306175766599912]\n",
    "# Episode: 2800, [-7.69945047297023, 4.63572107199487, 4.63572107199487]\n",
    "# Episode: 2900, [-7.640228784974167, 5.129701244255248, 5.129701244255248]\n",
    "# Episode: 3000, [-7.33452401443051, 4.234568124813538, 4.234568124813538]\n",
    "# Episode: 3100, [-7.561209771041727, 4.551318252296591, 4.551318252296591]\n",
    "# Episode: 3200, [-7.303825192093116, 4.1751459368803525, 4.1751459368803525]\n",
    "# Episode: 3300, [-7.4085041799390225, 4.324439976487989, 4.324439976487989]\n",
    "# Episode: 3400, [-8.831540597437234, 5.095912768930884, 5.095912768930884]\n",
    "# Episode: 3500, [-7.909255169344246, 4.814617328955552, 4.814617328955552]\n",
    "# Episode: 3600, [-8.102049625513107, 4.218137021221713, 4.218137021221713]\n",
    "# Episode: 3700, [-7.124044426425797, 4.22171591046473, 4.22171591046473]\n",
    "# Episode: 3800, [-9.855226095181644, 5.559444947358021, 5.559444947358021]\n",
    "# Episode: 3900, [-8.112882872673746, 4.601425710926074, 4.601425710926074]\n",
    "# Episode: 4000, [-7.7353843779903855, 4.842239161334104, 4.842239161334104]\n",
    "# Episode: 4100, [-7.877527887061531, 4.593953921896876, 4.593953921896876]\n",
    "# Episode: 4200, [-7.401751185392445, 4.52101055148277, 4.52101055148277]\n",
    "# Episode: 4300, [-8.233404140017905, 4.713286609882572, 4.713286609882572]\n",
    "# Episode: 4400, [-8.653939326472079, 5.184954272702421, 5.184954272702421]\n",
    "# Episode: 4500, [-9.767723118921353, 6.570082634111054, 6.570082634111054]\n",
    "# Episode: 4600, [-9.30060260689829, 5.242836047978754, 5.242836047978754]\n",
    "# Episode: 4700, [-8.964009029648428, 4.901113456984634, 4.901113456984634]\n",
    "# Episode: 4800, [-10.22982114177131, 5.669039384469422, 5.669039384469422]\n",
    "# Episode: 4900, [-10.568961308877448, 4.479337463298422, 4.479337463298422]\n",
    "# Episode: 5000, [-8.700993807143094, 4.4632810497979705, 4.4632810497979705]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 851
    },
    "executionInfo": {
     "elapsed": 705,
     "status": "ok",
     "timestamp": 1649958974522,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "wL6fHge0K_xT",
    "outputId": "dc2d1d95-a178-4bde-a06c-e736c447d0bc"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "return_array = np.array(return_list)\n",
    "for i, agent_name in enumerate([\"adversary_0\", \"agent_0\", \"agent_1\"]):\n",
    "    plt.figure()\n",
    "    plt.plot(\n",
    "        np.arange(return_array.shape[0]) * 100,\n",
    "        rl_utils.moving_average(return_array[:, i], 9))\n",
    "    plt.xlabel(\"Episodes\")\n",
    "    plt.ylabel(\"Returns\")\n",
    "    plt.title(f\"{agent_name} by MADDPG\")"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "第21章-多智能体强化学习进阶.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
